#include "ExampleLoadingBar.h"

#include "OgreResourceGroupManager.h"
#include "OgreException.h"
#include "OgreOverlay.h"
#include "OgreOverlayElement.h"
#include "OgreOverlayManager.h"
#include "OgreRenderWindow.h"

void GamePipeGame::ExampleLoadingBar::start( Ogre::RenderWindow* window, unsigned short numGroupsInit /*= 1*/, unsigned short numGroupsLoad /*= 1*/, Ogre::Real initProportion /*= 0.70f*/ )
{
	mWindow = window;
	mNumGroupsInit = numGroupsInit;
	mNumGroupsLoad = numGroupsLoad;
	mInitProportion = initProportion;
	// We need to pre-initialise the 'Bootstrap' group so we can use
	// the basic contents in the loading screen
	//GamePipe::ResourceManager::GetInstanceRef().LoadResourceGroup("Bootstrap");

	Ogre::OverlayManager& omgr = Ogre::OverlayManager::getSingleton();
	mLoadOverlay = (Ogre::Overlay*)omgr.getByName("LoadingBar/LoadOverlay");
	if (!mLoadOverlay)
	{
		OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, 
			"Cannot find loading overlay", "ExampleLoadingBar::start");
	}
	mLoadOverlay->show();

	// Save links to the bar and to the loading text, for updates as we go
	mLoadingBarElement = omgr.getOverlayElement("LoadingBar/LoadPanel/Bar/Progress");
	mLoadingCommentElement = omgr.getOverlayElement("LoadingBar/LoadPanel/Comment");
	mLoadingDescriptionElement = omgr.getOverlayElement("LoadingBar/LoadPanel/Description");

	Ogre::OverlayElement* barContainer = omgr.getOverlayElement("LoadingBar/LoadPanel/Bar");
	mProgressBarMaxSize = barContainer->getWidth();
	mLoadingBarElement->setWidth(0);

	// self is listener
	Ogre::ResourceGroupManager::getSingleton().addResourceGroupListener(this);
}

void GamePipeGame::ExampleLoadingBar::resourceGroupScriptingStarted( const Ogre::String& groupName, size_t scriptCount )
{
	assert(mNumGroupsInit > 0 && "You stated you were not going to init "
		"any groups, but you did! Divide by zero would follow...");
	// Lets assume script loading is 70%
	mProgressBarInc = mProgressBarMaxSize * mInitProportion / (Ogre::Real)scriptCount;
	mProgressBarInc /= mNumGroupsInit;
	mLoadingDescriptionElement->setCaption(" ");//Parsing scripts...");
	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::scriptParseStarted( const Ogre::String& scriptName, bool& skipThisScript )
{
	mLoadingCommentElement->setCaption(" ");//scriptName);
	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::resourceGroupScriptingEnded( const Ogre::String& groupName )
{

}

void GamePipeGame::ExampleLoadingBar::resourceGroupLoadStarted( const Ogre::String& groupName, size_t resourceCount )
{
	assert(mNumGroupsLoad > 0 && "You stated you were not going to load "
		"any groups, but you did! Divide by zero would follow...");
	mProgressBarInc = mProgressBarMaxSize * (1-mInitProportion) / 
		(Ogre::Real)resourceCount;
	mProgressBarInc /= mNumGroupsLoad;
	mLoadingDescriptionElement->setCaption("Loading resources...");
	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::worldGeometryStageStarted( const Ogre::String& description )
{
	mLoadingCommentElement->setCaption(description);
	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::resourceLoadEnded( void )
{

}

void GamePipeGame::ExampleLoadingBar::resourceLoadStarted( const Ogre::ResourcePtr& resource )
{
	mLoadingCommentElement->setCaption(resource->getName());
	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::scriptParseEnded( const Ogre::String& scriptName, bool skipped )
{
	Ogre::Real progressAmount = mLoadingBarElement->getWidth() + mProgressBarInc;
	if (progressAmount > mProgressBarMaxSize)
		mLoadingBarElement->setWidth(mProgressBarMaxSize);
	else
		mLoadingBarElement->setWidth(progressAmount);

	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::manualProgression( Ogre::Real progress )
{
	Ogre::Real progressAmount = mLoadingBarElement->getWidth() + progress;
	if( progressAmount > mProgressBarMaxSize )
		mLoadingBarElement->setWidth( mProgressBarMaxSize );
	else
		mLoadingBarElement->setWidth( progressAmount );

	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::resourceGroupLoadEnded( const Ogre::String& groupName )
{

}

void GamePipeGame::ExampleLoadingBar::worldGeometryStageEnded( void )
{
	Ogre::Real progressAmount = mLoadingBarElement->getWidth() + mProgressBarInc;
	if (progressAmount > mProgressBarMaxSize)
		mLoadingBarElement->setWidth(mProgressBarMaxSize);
	else
		mLoadingBarElement->setWidth(progressAmount);

	mWindow->update();
}

void GamePipeGame::ExampleLoadingBar::finish( void )
{
	// hide loading screen
	mLoadOverlay->hide();

	// Unregister listener
	Ogre::ResourceGroupManager::getSingleton().removeResourceGroupListener(this);
}